<template>
	<div v-if="located === 'Filter'">不支持富文本过滤</div>
	<div v-else style="border: 1px solid #ccc">
		<Toolbar :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
		<Editor :style="style" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" @onChange="handleChange" @onBlur="handleBlur" />
	</div>
</template>

<script lang="ts" setup>
import axios from 'axios';
import { IToolbarConfig, IDomEditor, IEditorConfig } from '@wangeditor/editor';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import '@wangeditor/editor/dist/css/style.css';
import useElement from './hooks/useElement';
import { TabFieldType, TablePageType } from '../custom/DataStructs/commontype';
import FileIns from '/@/components/Linxyun/FileClient/FileClientApi/file_instance.js';
import { SlateElement } from '@wangeditor/editor';

interface MyIDomEditor extends IDomEditor {
	FileUpload: () => void;
}
type ImageElement = SlateElement & {
	src: string;
	alt: string;
	url: string;
	href: string;
};
type InsertFnType = (url: string, alt?: string, href?: string) => void;
const props = withDefaults(
	defineProps<{
		pageInfo?: TablePageType;
		filterIdx: number;
		located: string;
		pageData?: any;
		inputData: Record<string, any>;
		globalData?: any;
		modelValue: string;
		FieldItem: TabFieldType | null;
	}>(),
	{
		located: 'table',
		filterIdx: -1,
		pageData: {},
		globalData: null,
		modelValue: '',
		FieldItem: null,
	}
);
const { FieldItem, located, inputData, pageData, globalData } = toRefs(props);
const emit = defineEmits(['update:modelValue']);
console.log('modelValue:' + props.modelValue);
const setting = localStorage.getItem('setting');
let frontUrl: string = '';
if (setting) {
	frontUrl = JSON.parse(setting).ImagUrl;
}
const fileClient = ref();
const InitFileIns = async () => {
	fileClient.value = await FileIns.instance();
};
InitFileIns();
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef<IDomEditor>();

// 模式
const mode = ref<'simple' | 'default'>('default');
// 内容 HTML
let valueHtml = ref<string>('');
let activate = ref<boolean>(true);
const style = reactive({
	height: '310px',
});
const contentUrl = ref('');

const toolbarConfig: Partial<IToolbarConfig> = {
	// excludeKeys: ['insertVideo', 'uploadVideo', 'editVideoSize'],
};

// 插入的图片 和上传的图片
const imageList = reactive<{
	instImage: string[];
	deleteImage: any[];
}>({
	instImage: [],
	deleteImage: [],
});
const editorConfig: Partial<IEditorConfig> = { placeholder: '请输入内容...', MENU_CONF: {} };
editorConfig.MENU_CONF!['uploadImage'] = {
	// 自定义上传
	async customUpload(file: File, insertFn: InsertFnType) {
		// file 即选中的文件
		// 自己实现上传，并得到图片 url alt href

		const url = await fileClient.value.uploadContent(file.name, file);
		console.log('customUpload', file, fileClient.value.uploadContent);
		// 最后插入图片

		console.log('url', frontUrl + url);

		insertFn(frontUrl + url);
	},
};
if (FieldItem.value!.DataStorageMode === 'file') {
	// editorConfig.MENU_CONF!['uploadImage'].base64LimitSize = 10 * 1024 * 1024;
}
editorConfig.MENU_CONF!['insertImage'] = {
	onInsertedImage(imageNode: ImageElement | null) {
		// TS 语法
		if (imageNode == null) return;

		const { src, alt, url, href } = imageNode;
		console.log('inserted image', src);

		imageList.instImage.push(src);
	},
};
editorConfig.MENU_CONF!['uploadVideo'] = {
	// 自定义上传
	async customUpload(file: File, insertFn: InsertFnType) {
		// file 即选中的文件
		// 自己实现上传，并得到视频 url poster
		const url = await fileClient.value.uploadContent(file.name, file);
		console.log('customUpload', file, fileClient.value.uploadContent);
		// 最后插入视频
		insertFn(frontUrl + url);
	},
};

const handleBlur = (e) => {
	console.log('handleBlur', e);
};
// 富文本创建回调
const handleCreated = (editor: MyIDomEditor) => {
	editorRef.value = editor; // 记录 editor 实例，重要！

	console.log('handleCreated', editor);
	if (activate.value) {
		editorRef.value.enable();
	} else {
		editorRef.value.disable();
	}
	const valueImage = editorRef.value?.getElemsByType('image');
	console.log('handleCreated valueImage', valueImage);
	if (valueImage && valueImage.length) {
		imageList.instImage = valueImage.map((item: any) => {
			return item.src;
		});
	}

	if (['Edit', 'Detail'].includes(located.value)) {
		initData();
	}
};

const initData = () => {
	if (FieldItem.value!.DataStorageMode === 'text' || (FieldItem.value!.pageType === 'page' && !FieldItem.value!.attrs.isSaveFile)) {
		valueHtml.value = props.modelValue;
		console.log('initData valueHtml:', valueHtml.value);
		editorRef.value?.setHtml(props.modelValue);
	} else if (FieldItem.value!.DataStorageMode === 'file' || (FieldItem.value!.pageType === 'page' && FieldItem.value!.attrs.isSaveFile)) {
		contentUrl.value = props.modelValue;
		let url = props.modelValue;
		if (!props.modelValue.startsWith('http')) {
			url = JSON.parse(localStorage.getItem('setting') as string).ImagUrl + props.modelValue;
		}
		axios.get(url).then((res: any) => {
			console.log('content', res.data);
			valueHtml.value = res.data;
		});
	}
};

const handleChange = (editor: IDomEditor) => {
	// console.log('handleChange editor content');
	emit('update:modelValue', editor.getHtml());
};

// 上传
const uploadSubmit = async () => {
	const valueImage = editorRef.value?.getElemsByType('image');
	if (valueImage) {
		imageList.deleteImage = imageList.instImage.map((url) => {
			const index = valueImage.findIndex((item: any) => url === item.src);
			if (index === -1) {
				return url;
			}
		});
	} else {
		imageList.deleteImage = imageList.instImage;
	}
	console.log('uploadSubmit,deleteImage', imageList.deleteImage);

	// 保存为文件
	if (FieldItem.value!.DataStorageMode === 'file' || (FieldItem.value!.pageType === 'page' && FieldItem.value!.attrs.isSaveFile)) {
		console.log('uploadSubmit content', valueHtml.value);
		if (valueHtml.value) {
			const res = await fileClient.value.uploadContent('tinymce.html', new Blob([valueHtml.value]));
			if (res) {
				// valueHtml.value = res;
				console.log('uploadSubmit', res);
				fileClient.value.deleteFile(contentUrl.value);
				for (let index in imageList.deleteImage) {
					fileClient.value.deleteFile(imageList.deleteImage[index]);
				}
				return res;
			}
		}
	}
};
if (!FieldItem.value?.pageType) {
	const { handleDisable } = useElement(located, FieldItem.value!, valueHtml, props);
	handleDisable(activate);
}

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
	const editor = editorRef.value;
	if (editor == null) return;
	editor.destroy();
	console.log('onBeforeUnmount', editor);
});

defineExpose({ uploadSubmit });
</script>

<style lang="scss" scoped></style>
